<template>
    <div
        ref="dragVerify"
        class="drag_verify"
        :style="dragVerifyStyle"
        @mousemove="dragMoving"
        @mouseup="dragFinish"
        @mouseleave="dragFinish"
        @touchmove="dragMoving"
        @touchend="dragFinish"
    >
        <div class="dv_progress_bar" :class="{ goFirst2: isOk }" ref="progressBar" :style="progressBarStyle"></div>
        <div class="dv_text" :style="textStyle" ref="message">
            <slot name="textBefore" v-if="$slots.textBefore"></slot>
            {{ message }}
            <slot name="textAfter" v-if="$slots.textAfter"></slot>
        </div>

        <div
            class="dv_handler dv_handler_bg"
            :class="{ goFirst: isOk }"
            @mousedown="dragStart"
            @touchstart="dragStart"
            ref="handler"
            :style="handlerStyle"
        >
            <a-icon :type="!isPassing ? handlerIcon : successIcon" :style="{ color: isPassing ? '#6c6' : '' }" />
        </div>
    </div>
</template>
<script>
export default {
    name: 'slideVerify',
    props: {
        isPassing: {
            type: Boolean,
            default: false,
        },
        width: {
            type: Number,
            default: 250,
        },
        height: {
            type: Number,
            default: 40,
        },
        text: {
            type: String,
            default: '请按住滑块拖动',
        },
        successText: {
            type: String,
            default: '验证通过',
        },
        background: {
            type: String,
            default: '#eee',
        },
        progressBarBg: {
            type: String,
            default: '#76c61d',
        },
        completedBg: {
            type: String,
            default: '#76c61d',
        },
        circle: {
            type: Boolean,
            default: false,
        },
        radius: {
            type: String,
            default: '0px',
        },
        handlerIcon: {
            type: String,
            default: 'double-right',
        },
        successIcon: {
            type: String,
            default: 'check-circle',
        },
        handlerBg: {
            type: String,
            default: '#fff',
        },
        textSize: {
            type: String,
            default: '14px',
        },
        textColor: {
            type: String,
            default: '#333',
        },
    },
    mounted: function () {
        const dragEl = this.$refs.dragVerify
        dragEl.style.setProperty('--textColor', this.textColor)
        dragEl.style.setProperty('--width', Math.floor(this.width / 2) + 'px')
        dragEl.style.setProperty('--pwidth', -Math.floor(this.width / 2) + 'px')
    },
    computed: {
        handlerStyle: function () {
            return {
                left: '0px',
                width: this.height + 'px',
                height: this.height + 'px',
                background: this.handlerBg,
            }
        },
        message: function () {
            return this.isPassing ? this.successText : this.text
        },
        dragVerifyStyle: function () {
            return {
                width: this.width + 'px',
                height: this.height + 'px',
                lineHeight: this.height + 'px',
                background: this.background,
                borderRadius: this.circle ? this.height / 2 + 'px' : this.radius,
            }
        },
        progressBarStyle: function () {
            return {
                background: this.progressBarBg,
                height: this.height + 'px',
                borderRadius: this.circle ? this.height / 2 + 'px 0 0 ' + this.height / 2 + 'px' : this.radius,
            }
        },
        textStyle: function () {
            return {
                height: this.height + 'px',
                width: this.width + 'px',
                fontSize: this.textSize,
            }
        },
    },
    data() {
        return {
            isMoving: false,
            x: 0,
            isOk: false,
        }
    },
    methods: {
        dragStart: function (e) {
            if (!this.isPassing) {
                this.isMoving = true
                var handler = this.$refs.handler
                this.x = (e.pageX || e.touches[0].pageX) - parseInt(handler.style.left.replace('px', ''), 10)
            }
            this.$emit('handlerMove')
        },
        dragMoving: function (e) {
            if (this.isMoving && !this.isPassing) {
                var _x = (e.pageX || e.touches[0].pageX) - this.x
                var handler = this.$refs.handler
                if (_x > 0 && _x <= this.width - this.height) {
                    handler.style.left = _x + 'px'
                    this.$refs.progressBar.style.width = _x + this.height / 2 + 'px'
                } else if (_x > this.width - this.height) {
                    handler.style.left = this.width - this.height + 'px'
                    this.$refs.progressBar.style.width = this.width - this.height / 2 + 'px'
                    this.passVerify()
                }
            }
        },
        dragFinish: function (e) {
            if (this.isMoving && !this.isPassing) {
                var _x = (e.pageX || e.changedTouches[0].pageX) - this.x
                if (_x < this.width - this.height) {
                    this.isOk = true
                    var that = this
                    setTimeout(function () {
                        that.$refs.handler.style.left = '0'
                        that.$refs.progressBar.style.width = '0'
                        that.isOk = false
                    }, 500)
                    this.$emit('passfail')
                } else {
                    var handler = this.$refs.handler
                    handler.style.left = this.width - this.height + 'px'
                    this.$refs.progressBar.style.width = this.width - this.height / 2 + 'px'
                    this.passVerify()
                }
                this.isMoving = false
            }
        },
        passVerify: function () {
            this.$emit('update:isPassing', true)
            this.isMoving = false
            var handler = this.$refs.handler
            this.$refs.progressBar.style.background = this.completedBg
            this.$refs.message.style['-webkit-text-fill-color'] = 'unset'
            this.$refs.message.style.animation = 'slidetounlock2 3s infinite'
            this.$refs.message.style.color = '#fff'
            this.$emit('passcallback')
        },
        reset: function () {
            const oriData = this.$options.data()
            for (const key in oriData) {
                if (Object.prototype.hasOwnProperty.call(oriData, key)) {
                    this.$set(this, key, oriData[key])
                }
            }
            var handler = this.$refs.handler
            var message = this.$refs.message
            handler.style.left = '0'
            this.$refs.progressBar.style.width = '0'
            message.style['-webkit-text-fill-color'] = 'transparent'
            message.style.animation = 'slidetounlock 3s infinite'
            message.style.color = this.background
        },
    },
}
</script>
<style lang="less" scoped>
.drag_verify {
    position: relative;
    background-color: #e8e8e8;
    text-align: center;
    overflow: hidden;
    border: 1px solid #e4e7eb;
    margin: 0 auto;
}
.drag_verify .dv_handler {
    position: absolute;
    top: 0px;
    left: 0px;
    cursor: move;
}
.drag_verify .dv_handler i {
    color: #666;
    padding-left: 0;
    font-size: 16px;
}
.drag_verify .dv_progress_bar {
    position: absolute;
    height: 34px;
    width: 0px;
}
.drag_verify .dv_text {
    position: absolute;
    top: 0px;
    color: transparent;
    -moz-user-select: none;
    -webkit-user-select: none;
    user-select: none;
    -o-user-select: none;
    -ms-user-select: none;
    background: -webkit-gradient(
        linear,
        left top,
        right top,
        color-stop(0, var(--textColor)),
        color-stop(0.4, var(--textColor)),
        color-stop(0.5, #fff),
        color-stop(0.6, var(--textColor)),
        color-stop(1, var(--textColor))
    );
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    -webkit-text-size-adjust: none;
    animation: slidetounlock 3s infinite;
}
.drag_verify .dv_text * {
    -webkit-text-fill-color: var(--textColor);
}
.goFirst {
    left: 0px !important;
    transition: left 0.5s;
}
.goFirst2 {
    width: 0px !important;
    transition: width 0.5s;
}
</style>
<style>
@keyframes slidetounlock {
    0% {
        background-position: var(--pwidth) 0;
    }
    100% {
        background-position: var(--width) 0;
    }
}
@keyframes slidetounlock2 {
    0% {
        background-position: var(--pwidth) 0;
    }
    100% {
        background-position: var(--pwidth) 0;
    }
}
</style>